#include "serversocket.h"
#include "SQLParser.h"
#include "SQLParserResult.h"
#include "Dict.h"
#include "Timer.h"
#include <sstream>
#include "PlanGenerator.h"
#include "ASTPrinter.h"
#include "buffer.h"
using namespace ment;
using namespace std;

// ==================== NetworkConnectionManager 实现 ====================

NetworkConnectionManager::NetworkConnectionManager() : listenSocket(INVALID_SOCKET), isInitialized(false) {
}

NetworkConnectionManager::~NetworkConnectionManager() {
    shutdown();
}

bool NetworkConnectionManager::initialize() {
    if (isInitialized) return true;

    if (!initWinsock()) {
        cout << "Network protocol stack initialization failed!" << endl;
        return false;
    }

    isInitialized = true;
    return true;
}

bool NetworkConnectionManager::initWinsock() {
    WSADATA wsaData;
    WORD version = MAKEWORD(2, 2);
    return WSAStartup(version, &wsaData) == 0;
}

bool NetworkConnectionManager::startListening(int port) {
    if (!isInitialized) {
        cout << "Network manager not initialized!" << endl;
        return false;
    }

    // 创建监听socket
    listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (listenSocket == INVALID_SOCKET) {
        cout << "Failed to create listening socket!" << endl;
        return false;
    }

    // 设置服务器地址
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(port);
    serverAddr.sin_addr.S_un.S_addr = INADDR_ANY;

    // 绑定地址
    if (::bind(listenSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
        cout << "Address binding failed!" << endl;
        closesocket(listenSocket);
        return false;
    }

    // 开始监听
    if (listen(listenSocket, max_thread_num) == SOCKET_ERROR) {
        cout << "Failed to start listening!" << endl;
        closesocket(listenSocket);
        return false;
    }

    cout << Timer::getCurTime() << ": Database server is listening on port " << port << "..." << endl;
    return true;
}

SOCKET NetworkConnectionManager::acceptConnection() {
    sockaddr_in clientAddr;
    int addrLen = sizeof(clientAddr);
    return accept(listenSocket, (sockaddr*)&clientAddr, &addrLen);
}

void NetworkConnectionManager::closeConnection(SOCKET socket) {
    if (socket != INVALID_SOCKET) {
        closesocket(socket);
    }
}

void NetworkConnectionManager::shutdown() {
    if (listenSocket != INVALID_SOCKET) {
        // 在Windows上，关闭socket会导致accept()返回INVALID_SOCKET
        // 这样可以中断阻塞的accept()调用
        ::shutdown(listenSocket, SD_BOTH);  // 先关闭发送和接收
        closesocket(listenSocket);
        listenSocket = INVALID_SOCKET;
    }

    if (isInitialized) {
        cleanupWinsock();
        isInitialized = false;
    }
}

void NetworkConnectionManager::cleanupWinsock() {
    WSACleanup();
}

// ==================== SessionManager 实现 ====================

SessionManager::SessionManager() : nextSessionId(1) {
}

int SessionManager::createSession(SOCKET socket, const string& address) {
    lock_guard<mutex> lock(sessionMutex);

    int sessionId = nextSessionId++;
    auto clientInfo = make_shared<ClientInfo>();
    clientInfo->socket = socket;
    clientInfo->sessionId = sessionId;
    clientInfo->address = address;
    clientInfo->isAuthenticated = false;

    sessions[sessionId] = clientInfo;
    return sessionId;
}

bool SessionManager::authenticateUser(int sessionId, const string& username, const string& password) {
    lock_guard<mutex> lock(sessionMutex);

    auto it = sessions.find(sessionId);
    if (it == sessions.end()) return false;

    // 验证用户凭据
    Dict* userDict = Dict::getInstance();
    User* user = userDict->GetUser(username);
    bool authSuccess = user != nullptr &&
        user->GetUsername() == username &&
        user->GetCode() == password;
    delete user;

    if (authSuccess) {
        it->second->isAuthenticated = true;
        it->second->username = username;
        cout << Timer::getCurTime() << ": User " << username << " login" << endl;
    }

    return authSuccess;
}

string SessionManager::getUsername(int sessionId) {
    lock_guard<mutex> lock(sessionMutex);

    auto it = sessions.find(sessionId);
    if (it != sessions.end() && it->second->isAuthenticated) {
        return it->second->username;
    }
    return "";
}

bool SessionManager::isAuthenticated(int sessionId) {
    lock_guard<mutex> lock(sessionMutex);

    auto it = sessions.find(sessionId);
    return it != sessions.end() && it->second->isAuthenticated;
}

void SessionManager::removeSession(int sessionId) {
    lock_guard<mutex> lock(sessionMutex);

    auto it = sessions.find(sessionId);
    if (it != sessions.end()) {
        if (it->second->isAuthenticated) {
            cout << Timer::getCurTime() << ": User " << it->second->username << " disconnected" << endl;
        }
        sessions.erase(it);
    }
}

// ==================== MessageProcessor 实现 ====================

MessageProcessor::MessageProcessor() {
}

bool MessageProcessor::sendMessage(SOCKET socket, const string& message) {
    // 只发送字符串内容，不包含额外的null终止符
    int result = send(socket, message.c_str(), message.length(), 0);
    return result != SOCKET_ERROR;
}

string MessageProcessor::receiveMessage(SOCKET socket) {
    char buffer[BUFFER_SIZE + 5];
    int bytesReceived = recv(socket, buffer, BUFFER_SIZE, 0);

    if (bytesReceived > 0) {
        // 确保缓冲区以null结尾，但不覆盖接收到的数据
        if (bytesReceived < BUFFER_SIZE) {
            buffer[bytesReceived] = '\0';
        } else {
            buffer[BUFFER_SIZE - 1] = '\0';
        }
        
        // 如果接收到的数据已经包含null终止符，创建字符串时会自动处理
        return string(buffer);
    }

    return "";
}

bool MessageProcessor::processAuthenticationRequest(SOCKET socket, string& username, string& password) {
    // 接收用户名
    username = receiveMessage(socket);
    if (username.empty() || username == "exit") {
        return false;
    }

    // 接收密码
    password = receiveMessage(socket);
    if (password.empty() || password == "exit") {
        return false;
    }

    return true;
}

// ==================== SQLCommandHandler 实现 ====================

static const char* stmtTypeStr(StatementType t) {
    switch (t) {
    case ForSelect: return "SELECT";
    case ForCreate: return "CREATE";
    case ForInsert: return "INSERT";
    case ForDelete: return "DELETE";
    case ForUpdate: return "UPDATE";
    case ForPrepare: return "PREPARE";
    case ForExecute: return "EXECUTE";
    default: return "UNKNOWN";
    }
}

string SQLCommandHandler::executeCommand(const string& sqlCommand, const string& username) {
    Timer::start(username);
    stringstream resultStream;

    SQLParserResult parseResult;
    SQLParser::parse(sqlCommand, &parseResult);

    // 语法解析失败
    if (!parseResult.isValid()) {
        cout << parseResult.errorMsg() << endl;
        return string(parseResult.errorMsg()) + "\n";
    }

    for (auto statement : parseResult.getStatements()) {
        //9.12
        ASTPrinter printer;
        std::string astStr = printer.print(statement);
        std::cout << "[AST]\n" << astStr << std::endl;       //只输出在服务端


        string executionResult = statement->execute(username);

        // 检查执行错误
        if (!executionResult.empty() && executionResult.find("Error:") == 0) {
            // 替换占位符为实际值
            size_t linePos = executionResult.find("(line 0");
            if (linePos != string::npos) {
                executionResult.replace(linePos + 6, 1, to_string(statement->errorLine));
            }
            size_t colPos = executionResult.find("(column 0");
            if (colPos != string::npos) {
                executionResult.replace(colPos + 7, 1, to_string(statement->errorColumn));
            }

            cout << "[SEMANTIC-ERROR] " << executionResult << endl;
            resultStream << executionResult << endl;
            continue;
        }

        // 聚合所有执行结果
        resultStream << executionResult << endl;

        // 生成执行计划
        std::unique_ptr<ment::PlanNode> plan(ment::PlanGenerator::generate(statement));
        if (plan) {
            std::cout << "[PLAN] " << plan->toJSON() << std::endl;
        }
        else {
            std::cout << "[PLAN-ERROR] \"" << stmtTypeStr(statement->type())
                << "\" is not yet supported in execution plan generation.\n";
        }

        // 输出缓存统计信息
        Buffer* buffer = Buffer::getInstance();
        buffer->logBufferStats();
    }

    Timer::end(username);
    resultStream << Timer::outputInterval(username);

    return resultStream.str();
}

string SQLCommandHandler::formatErrorMessage(const string& error, int line, int column) {
    string formattedError = error;
    // 这里可以添加更多的错误格式化逻辑
    return formattedError;
}

// ==================== DatabaseServer 实现 ====================

DatabaseServer::DatabaseServer() : isRunning(false) {
    connectionManager = make_unique<NetworkConnectionManager>();
    sessionManager = make_unique<SessionManager>();
    messageProcessor = make_unique<MessageProcessor>();
}

DatabaseServer::~DatabaseServer() {
    stop();
}

bool DatabaseServer::start(int port) {
    lock_guard<mutex> lock(serverMutex);

    if (isRunning) {
        cout << "Server is already running!" << endl;
        return false;
    }

    // 初始化网络连接管理器
    if (!connectionManager->initialize()) {
        cout << "Network connection manager initialization failed!" << endl;
        return false;
    }

    // 开始监听
    if (!connectionManager->startListening(port)) {
        cout << "Server listening startup failed!" << endl;
        return false;
    }

    isRunning = true;
    system("cls");
    cout << Timer::getCurTime() << ": Database server started successfully, waiting for client connections..." << endl;

    // 主循环，接受客户端连接
    while (isRunning) {
        SOCKET clientSocket = connectionManager->acceptConnection();
        if (clientSocket == INVALID_SOCKET) {
            if (isRunning) {
                cout << "Failed to accept client connection!" << endl;
                continue;
            }
            else {
                // 服务器正在关闭，accept()被中断，正常退出循环
                break;
            }
        }

        // 为每个客户端创建处理线程
        string clientAddress = "unknown"; // 可以获取实际的客户端地址
        clientThreads.emplace_back(&DatabaseServer::handleClient, this, clientSocket, clientAddress);
    }

    // 等待所有客户端线程结束
    for (auto& thread : clientThreads) {
        if (thread.joinable()) {
            thread.join();
        }
    }

    return true;
}

void DatabaseServer::stop() {
    {
        lock_guard<mutex> lock(serverMutex);
        if (!isRunning) return;
        isRunning = false;
    }

    cout << Timer::getCurTime() << ": Shutting down database server..." << endl;

    // 关闭网络连接管理器
    connectionManager->shutdown();

    // 等待所有客户端线程结束
    cout << Timer::getCurTime() << ": Waiting for client connections to close..." << endl;
    for (auto& thread : clientThreads) {
        if (thread.joinable()) {
            thread.join();
        }
    }
    clientThreads.clear();

    cout << Timer::getCurTime() << " : server closed" << endl;
}

void DatabaseServer::handleClient(SOCKET clientSocket, const string& clientAddress) {
    // 创建会话
    int sessionId = sessionManager->createSession(clientSocket, clientAddress);

    try {
        // 执行客户端认证
        if (!performClientAuthentication(clientSocket, sessionId)) {
            cout << "Client authentication failed, connection closed" << endl;
            connectionManager->closeConnection(clientSocket);
            sessionManager->removeSession(sessionId);
            return;
        }

        // 处理客户端命令
        processClientCommands(clientSocket, sessionId);

    }
    catch (const exception& e) {
        cout << "Exception occurred while handling client: " << e.what() << endl;
    }

    // 清理资源
    connectionManager->closeConnection(clientSocket);
    sessionManager->removeSession(sessionId);
}

bool DatabaseServer::performClientAuthentication(SOCKET socket, int sessionId) {
    while (true) {
        string username, password;

        // 处理认证请求
        if (!messageProcessor->processAuthenticationRequest(socket, username, password)) {
            return false; // 客户端断开或exit
        }

        // 验证用户凭据
        if (sessionManager->authenticateUser(sessionId, username, password)) {
            messageProcessor->sendMessage(socket, "pass");
            return true; // 认证成功
        }
        else {
            messageProcessor->sendMessage(socket, "用户名或密码错误，请重新输入。\n");
        }
    }
}

void DatabaseServer::processClientCommands(SOCKET socket, int sessionId) {
    string username = sessionManager->getUsername(sessionId);
    int commandCount = 0; // 命令计数器

    while (isRunning && sessionManager->isAuthenticated(sessionId)) {
        // 接收SQL命令
        string sqlCommand = messageProcessor->receiveMessage(socket);

        if (sqlCommand.empty()) {
            break; // 连接断开
        }

        cout << Timer::getCurTime() << ": Received SQL command from user " << username << ": " << sqlCommand << endl;

        if (sqlCommand == "exit") {
            break; // 客户端请求断开
        }

        // 执行SQL命令
        string result = SQLCommandHandler::executeCommand(sqlCommand, username);

        // 发送执行结果
        messageProcessor->sendMessage(socket, result);

        // 增加命令计数器，每5个命令输出一次缓存统计
        commandCount++;
        if (commandCount % 5 == 0) {
            cout << "[BUFFER-STATS] Buffer statistics after processing " << commandCount << " commands:" << endl;
            Buffer* buffer = Buffer::getInstance();
            buffer->logBufferStats();
        }
    }
}